﻿using System;
using System.Linq;
using Medianamik.UI.Controls;
using Telerik.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI;
using Medianamik.UI.Lock;
using Medianamik.Core;
using Medianamik.Core.Interfaces;

namespace Medianamik.UI
{
    public abstract class BaseModuleListUserControl : BaseUserControl
    {
        const string _lockInfoToolTipID = "BFD7C318-8ABD-4CA2-90BE-7605DCC2F5E1";
        const string _actionColumnID = "F1059009-C12A-4626-9D41-F7F4A5AD75D0";
        const string _deleteNodeWindowId = "G1059009C12A46269D41F7F4A5AD75D0";

        protected override void OnInit(EventArgs e)
        {
            Page.CultureChanged += Page_CultureChanged;
            var windowAdded = false;
            var deleteNodeWindow = new BaseModalWindow();

            if (!Page.MyWindowManager.Windows.Cast<RadWindow>()
                .Any(w => w.ID.Equals(_deleteNodeWindowId)))
            {
                deleteNodeWindow.ID = _deleteNodeWindowId;
                Page.MyWindowManager.Windows.Add(deleteNodeWindow);
                windowAdded = true;
            }

            if (!Page.MyWindowManager.Windows.Cast<RadWindow>()
               .Any(w => w.ID.Equals(_lockInfoToolTipID)))
            {
                var lockInfoToolTip = new LockInfoToolTip();
                lockInfoToolTip.ID = _lockInfoToolTipID;
                GridUpdatePanel.ContentTemplateContainer.Controls.Add(lockInfoToolTip);
            }

            var actionColumn = new GridTemplateColumn();
            Grid.MasterTableView.EnableColumnsViewState = false;
            Grid.MasterTableView.Columns.Add(actionColumn);
            actionColumn.ItemStyle.CssClass = "Actions";
            actionColumn.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
            actionColumn.HeaderStyle.Width = Unit.Percentage(1);
            actionColumn.HeaderText = "Actions";
            actionColumn.UniqueName = _actionColumnID;
            actionColumn.ItemTemplate = new GridItemTemplate(NodeIdParamName, ManagementURL,
                LockRequestFailed);

            const string sharedScriptControlId = "ad5db9009d544e0b88a419bb6e9ce64b";
            var sharedScriptControl = Page.MyRadScriptBlock.FindControl(sharedScriptControlId) as Literal;
            if (sharedScriptControl == null)
            {
                sharedScriptControl = new Literal();
                sharedScriptControl.ID = sharedScriptControlId;
                Page.MyRadScriptBlock.Controls.Add(sharedScriptControl);
            }

            if (!Page.IsPostBack)
            {
                var script = String.Concat("<script type=\"text/javascript\">//<![CDATA[ \n",
                    Utility.GetDeleteElementScript(Page.MyRadAjaxManager.ClientID, 
                        Medianamik.Core.Pages.DeleteElementWindow, Page.CurrentEditionCulture.Name,DestroyOnDelete,
                        Page.CurrentEditionCulture.Name == ""),
                    Utility.GetRowDroppingScript(Grid.ClientID),
                    " //]]></script>\n");

                if (windowAdded)
                {
                    deleteNodeWindow.OnClientClose = "deleteNodeWindowCallback";
                    deleteNodeWindow.IconUrl = "/Medianamik/images/Icones/Ico_Supprimer.gif";
                    deleteNodeWindow.ReloadOnShow = true;
                    deleteNodeWindow.Width = Unit.Pixel(400);
                    deleteNodeWindow.Height = Unit.Pixel(200);
                }

                if (EnableSorting)
                {
                    Grid.ClientSettings.AllowRowsDragDrop = true;
                    Grid.ClientSettings.EnableRowHoverStyle = true;
                    Grid.ClientSettings.Selecting.AllowRowSelect = true;
                    Grid.ClientSettings.Selecting.EnableDragToSelectRows = true;
                    Grid.ClientSettings.ClientEvents.OnRowDropping = "onRowDropping";
                }

                sharedScriptControl.Text = script;
            }

            base.OnInit(e);
        }

        void Page_CultureChanged(object sender, CultureChangedEventArgs e)
        {
            Grid.DataBind();
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Grid.NeedDataSource += new GridNeedDataSourceEventHandler(GridNeedDataSource);
            Grid.RowDrop += new GridDragDropEventHandler(Grid_RowDrop);
            RadAjaxManager.GetCurrent(Page).AjaxRequest += new RadAjaxControl.AjaxRequestDelegate(AjaxRequest);
        }

        protected override void OnPreRender(EventArgs e)
        {
            // Enregister le service de Lock systématiquement
            // Correction du bug : Le service de Lock n'est pas ajouté après un callback ajax.
            ScriptManager.GetCurrent(Page).Services.Add(new ServiceReference("/Medianamik/Services/LockWebService.asmx"));

            
            base.OnPreRender(e);
        }

        void Grid_RowDrop(object sender, GridDragDropEventArgs e)
        {
            if (EnableSorting && e.DraggedItems[0].OwnerGridID == Grid.ClientID)
            {
                Guid destinationNodeId;
                Node movedNode = NodeManager.GetNode((Guid)e.DraggedItems[0].GetDataKeyValue(Grid.MasterTableView.DataKeyNames[0]));
                if (string.IsNullOrEmpty(e.HtmlElement) && movedNode != null)
                {
                    destinationNodeId = (Guid)e.DestDataItem.GetDataKeyValue(Grid.MasterTableView.DataKeyNames[0]);

                    DropPosition pos = e.DropPosition == GridItemDropPosition.Above
                                          ? DropPosition.Above
                                          : DropPosition.Below;
                  
                    NodeManager.ChangeNodeOrder(movedNode, destinationNodeId, pos);

                    Grid.Rebind();
                }
            }
        }

        protected abstract void GridNeedDataSource(object source, GridNeedDataSourceEventArgs e);

        void unlockButton_Click(object sender, EventArgs e)
        {
            var lockInfoToolTip = (RadToolTip)GridUpdatePanel.ContentTemplateContainer.FindControlR(_lockInfoToolTipID);

            lockInfoToolTip.Visible = false;
        }

        public virtual void AjaxRequest(object sender, AjaxRequestEventArgs e)
        {
            Grid.Rebind();
            GridUpdatePanel.Update();
        }

        protected void LockRequestFailed(object sender, CommandEventArgs e)
        {
            Grid.Rebind();
            Guid objectId = new Guid((string)e.CommandArgument);
            LockInfoToolTip lockInfoToolTip = (LockInfoToolTip)GridUpdatePanel.ContentTemplateContainer.FindControlR(_lockInfoToolTipID);
            lockInfoToolTip.ObjectId = objectId;
            lockInfoToolTip.DataBind();
            lockInfoToolTip.Show();
        }

        protected virtual void Delete(object source, GridCommandEventArgs e)
        {
            GridEditableItem item = e.Item as GridEditableItem;
            Guid nodeId = (Guid)item.GetDataKeyValue(NodeIdParamName);
            NodeManager.DestroyNode(nodeId);
            Grid.Rebind();
        }

        protected abstract RadGrid Grid
        {
            get;
        }

        protected abstract UpdatePanel GridUpdatePanel
        {
            get;
        }

        protected abstract string ManagementURL
        {
            get;
        }

        protected string NodeIdParamName
        {
            get { return "id"; }
        }

        protected virtual bool DestroyOnDelete
        {
            get { return false; }
        }

        protected virtual bool EnableSorting
        {
            get { return false; }
        }

        class GridItemTemplate : ITemplate
        {
            string _managementURL;
            CommandEventHandler _lockRequestFailedHandler;
            string _nodeIdParamName;

            public GridItemTemplate(string nodeIdParamName, string managementURL,
                CommandEventHandler lockRequestFailedHandler)
            {
                _managementURL = managementURL;
                _lockRequestFailedHandler = lockRequestFailedHandler;
                _nodeIdParamName = nodeIdParamName;
            }

            private void BindDeleteButton(Object s, EventArgs e)
            {
                GridDataItem container = (GridDataItem)_deleteButton.NamingContainer;
                var node = ((INode)container.DataItem);

                _deleteButton.OnClientRequestSucceeded =
                    String.Format("openDeleteNodeWindow(\"{0}\")", node.ID.ToString());
                _deleteButton.NodeId = node.ID;
            }

            private void BindEditButton(Object s, EventArgs e)
            {
                GridDataItem container = (GridDataItem)_editButton.NamingContainer;
                var node = ((INode)container.DataItem);

                _editButton.NavigateUrl = String.Format("{0}?{1}={2}",
                    _managementURL, _nodeIdParamName, node.ID.ToString());
                _editButton.NodeId = node.ID;
            }

            LockButton _editButton;
            LockButton _deleteButton;

            public void InstantiateIn(System.Web.UI.Control container)
            {
                Table table = new Table();
                container.Controls.Add(table);
                table.CellPadding = 0;
                table.CellSpacing = 0;
                table.BorderWidth = 0;
                table.Attributes.Add("align", "center");

                TableRow tableRow = new TableRow();
                table.Rows.Add(tableRow);

                TableCell editTableCell = new TableCell();
                tableRow.Cells.Add(editTableCell);

                _editButton = new LockButton();
                editTableCell.Controls.Add(_editButton);
                _editButton.ID = "editButton";
                _editButton.ImageUrl = "/Medianamik/images/Icones/Ico_Edition.gif";
                _editButton.LockedOrDisabledImageUrl = "/Medianamik/images/Icones/Ico_EditionInactif.gif";
                _editButton.RequestFailed += _lockRequestFailedHandler;
                _editButton.DataBinding += new EventHandler(BindEditButton);

                TableCell deleteTableCell = new TableCell();
                tableRow.Cells.Add(deleteTableCell);

                _deleteButton = new LockButton();
                deleteTableCell.Controls.Add(_deleteButton);
                _deleteButton.ID = "deleteButton";
                _deleteButton.ImageUrl = "/medianamik/images/Icones/Ico_Supprimer.gif";
                _deleteButton.LockedOrDisabledImageUrl = "/medianamik/images/Icones/Ico_SupprimerInactif.gif";
                _deleteButton.RequestFailed += _lockRequestFailedHandler;
                _deleteButton.DataBinding += new EventHandler(BindDeleteButton);
            }
        }
    }
}